package com.yootoo.extpmml.controller;

import com.alibaba.fastjson.JSON;
import com.yootoo.extpmml.Entites.model.ModelDesc;
import com.yootoo.extpmml.service.BaseOperateService;
import com.yootoo.extpmml.utils.ModelHelper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Map;

/**
 * 模型管理
 */
@Controller
public class ModelController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ModelController.class);

    @Autowired
    private BaseOperateService<ModelDesc> modelOperateService;

    @GetMapping(value = "/index")
    public String index(){
        return "upload";
    }

    @GetMapping(value = "/")
    public String home(){
        return "upload";
    }


    @PostMapping("/upload")
    public @ResponseBody String singleFileUpload(@RequestParam("source") String source,@RequestParam("name") String name
            ,@RequestParam("features") String features
            ,@RequestParam("extension") String extension,@RequestParam("model") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {
        if (file.isEmpty()) {
            return "请选择文件";
        }

        if (name == null || name.trim().length() == 0){
            return "请填写模型name";
        }

        if (source == null || source.trim().length() == 0){
            return "请填写模型来源,Evaluator、Booster、Drools或Smg3";
        }
        if (features == null || features.trim().length() == 0){
            return "请填写模型输入特征";
        }
        if (source.trim().equalsIgnoreCase("smg3") && StringUtils.isBlank(extension)){
            return "smg3需要填写extension(ser包信息,包含alias和signature),如 {\"alias\":aaa,\"signature\":bbb}";
        }

        ModelDesc modelDesc = new ModelDesc();
        try {
            modelDesc.setPmml(IOUtils.toByteArray(file.getInputStream()));
            modelDesc.setSource(source);
            modelDesc.setState(0);
            modelDesc.setName(name);
            modelDesc.setFeatures(features);
            modelDesc.setExtension(extension);
            ModelHelper.toEvaluator(modelDesc);
            modelOperateService.upload(modelDesc);
        } catch (Exception e) {
            LOGGER.error("模型上传失败",e);
            return e.getMessage();
        }
        return "模型上传成功\n" + modelDesc.toString();
    }

    @GetMapping(value = "/update")
    public String update(){
        return "update";
    }


    @PostMapping("/update")
    public @ResponseBody String singleFileUpdate(@RequestParam("source") String source,@RequestParam("name") String name,
                                                 @RequestParam("features") String features,
                                                 @RequestParam("extension") String extension,
                                                 @RequestParam("model") MultipartFile file,
                                                 @RequestParam("force") Boolean force,
                                                 RedirectAttributes redirectAttributes) {
        if (file.isEmpty()) {
            return "请选择文件";
        }

        if (name == null || name.trim().length() == 0){
            return "请填写模型name";
        }

        if (source == null || source.trim().length() == 0){
            return "请填写模型来源,Evaluator或Booster";
        }

        if (features == null || features.trim().length() == 0){
            return "请填写模型输入特征";
        }

        if (source.trim().equalsIgnoreCase("smg3") && StringUtils.isBlank(extension)){
            return "smg3需要填写extension(ser包信息,包含alias和signature),如 {\"alias\":aaa,\"signature\":bbb}";
        }

        ModelDesc modelDesc = new ModelDesc();
        try {
            modelDesc.setPmml(IOUtils.toByteArray(file.getInputStream()));
            modelDesc.setSource(source);
            modelDesc.setState(0);
            modelDesc.setName(name);
            modelDesc.setFeatures(features);
            modelDesc.setExtension(extension);
            ModelHelper.toEvaluator(modelDesc);
            modelOperateService.update(modelDesc,force);
        } catch (Exception e) {
            LOGGER.error("模型更新失败",e);
            return e.getMessage();
        }
        return "模型更新成功\n" + modelDesc.toString();
    }


    @GetMapping("/up")
    public String up(){
        return "up";
    }

    @PostMapping(value = "/up")
    public @ResponseBody String up(@RequestParam String name){
        ModelDesc model;
        try {
            model = modelOperateService.up(name);
        }catch (Exception e){
            return e.getMessage();
        }
        return "上线成功:" + model;
    }

    @GetMapping("/down")
    public String down(){
        return "down";
    }

    @PostMapping(value = "/down")
    public @ResponseBody String down(@RequestParam String name){
        ModelDesc model;
        try {
            model = modelOperateService.down(name);
        }catch (Exception e){
            return e.getMessage();
        }
        return "下线成功:" + model;
    }



    @GetMapping("/test")
    public String test(){
        return "test";
    }

    @PostMapping(value = "/test")
    public @ResponseBody String test(@RequestParam String name,
                                     @RequestParam String vars){
        if (StringUtils.isBlank(name) ||
                StringUtils.isBlank(vars)){
            return "输入不能存在未空";
        }
        Map<String, Object> res = null;
        try {
            long start = System.currentTimeMillis();
            res = modelOperateService.test(name, vars);
            long end = System.currentTimeMillis();
            LOGGER.info("exec model :{} success. {}ms",name,end - start);
        }catch (Exception e){
            LOGGER.error("模型test失败",e);
            return e.getMessage();
        }
        return "测试成功,模型执行返回结果:" + JSON.toJSONString(res);
    }

}
